package jp.co.cyberagent.android.gpuimage.sample.utils;

import jp.co.cyberagent.android.gpuimage.GPUImage;
import jp.co.cyberagent.android.gpuimage.sample.utils.CameraHelper.CameraInfo2;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;

public class GLCameraLoader {
	private int mCurrentCameraId = 0;
	private Camera mCameraInstance;

	private CameraHelper mCameraHelper;
	private Activity mContext;
	private GPUImage mGPUImage;

	public GLCameraLoader(Activity context, GPUImage gpuImage,
			CameraHelper helper) {
		this.mContext = context;
		this.mCameraHelper = helper;
		this.mGPUImage = gpuImage;

	}

	public void onResume() {
		setUpCamera(mCurrentCameraId);
	}

	public void onPause() {
		releaseCamera();
	}

	public void switchCamera() {
		releaseCamera();
		mCurrentCameraId = (mCurrentCameraId + 1)
				% mCameraHelper.getNumberOfCameras();
		setUpCamera(mCurrentCameraId);
	}

	private void setUpCamera(final int id) {
		mCameraInstance = getCameraInstance(id);
		Parameters parameters = mCameraInstance.getParameters();
		// TODO adjust by getting supportedPreviewSizes and then choosing
		// the best one for screen size (best fill screen)
		parameters.setPreviewSize(720, 480);
		if (parameters.getSupportedFocusModes().contains(
				Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
			parameters
					.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
		}
		mCameraInstance.setParameters(parameters);

		int orientation = mCameraHelper.getCameraDisplayOrientation(mContext,
				mCurrentCameraId);
		CameraInfo2 cameraInfo = new CameraInfo2();
		mCameraHelper.getCameraInfo(mCurrentCameraId, cameraInfo);
		boolean flipHorizontal = cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT ? true
				: false;
		mGPUImage.setUpCamera(mCameraInstance, orientation, flipHorizontal,
				false);
	}

	/** A safe way to get an instance of the Camera object. */
	private Camera getCameraInstance(final int id) {
		Camera c = null;
		try {
			c = mCameraHelper.openCamera(id);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return c;
	}

	private void releaseCamera() {
		mCameraInstance.setPreviewCallback(null);
		mCameraInstance.release();
		mCameraInstance = null;
	}
}
